/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: Dec 31, 2009
 * Time: 10:52:24 AM
 * To change this template use File | Settings | File Templates.
 */
import dk.brics.automaton.Automaton;
import java.util.List;
import java.util.Set;
import org.jdom.Element;

// Referenced classes of package dk.brics.dsd:
//            Regexp, InternalSchemaErrorException, Validator, Context,
//            Schema

class RepeatRegexp extends Regexp
{

    RepeatRegexp(Element element, Schema schema)
    {
        try
        {
            String s = element.getAttributeValue("number");
            if(s != null)
                number = new Integer(s);
            s = element.getAttributeValue("min");
            if(s != null)
                min = new Integer(s);
            s = element.getAttributeValue("max");
            if(s != null)
                max = new Integer(s);
        }
        catch(NumberFormatException numberformatexception)
        {
            throw new InternalSchemaErrorException();
        }
        exp = parseOne(element, schema);
    }

    public Element toXML(Context context)
    {
        Element element = (new Element("repeat", "http://www.brics.dk/DSD/2.0")).addContent(exp.toXML(context));
        if(number != null)
            element.setAttribute("number", number.toString());
        if(min != null)
            element.setAttribute("min", min.toString());
        if(max != null)
            element.setAttribute("max", max.toString());
        return element;
    }

    boolean match(String s, Context context)
    {
        if(!exp.isChar(context))
            return super.match(s, context);
        if(min != null && s.length() < min.intValue() || max != null && s.length() > max.intValue() || number != null && s.length() != number.intValue())
            return false;
        for(int i = 0; i < s.length(); i++)
            if(!exp.match(s.substring(i, i + 1), context))
                return false;

        return true;
    }

    Automaton toAutomaton(Context context)
    {
        Automaton automaton = exp.toAutomaton(context);
        if(number != null)
            automaton = automaton.repeat(number.intValue(), number.intValue());
        else
        if(min == null && max == null)
            automaton = automaton.repeat();
        else
        if(min != null && max != null)
            automaton = automaton.repeat(min.intValue(), max.intValue());
        else
        if(min == null && max != null)
        {
            automaton = automaton.repeat(0, max.intValue());
        } else
        {
            int i = min.intValue();
            if(!Validator.repeat_hack || context.sg == null || i != 1)
                automaton = automaton.repeat(i);
            else
                automaton = automaton.repeat();
        }
        automaton.minimize();
        return automaton;
    }

    void addBoolexps(Context context, Set set)
    {
        exp.addBoolexps(context, set);
    }

    void getMentioned(Context context, Set set, List list)
    {
        exp.getMentioned(context, set, list);
    }

    boolean checkRepeatUnion(Context context)
    {
        if(max != null || min != null && min.intValue() > 0)
            return false;
        else
            return exp.checkRepeatUnion(context) || exp.checkUnion(context) || exp.checkSimple(context);
    }

    Integer number;
    Integer min;
    Integer max;
    Regexp exp;
}
